home *** CD-ROM | disk | FTP | other *** search
- Path: engnews1.Eng.Sun.COM!taumet!clamage
- From: James Kanze US/ESC 60/3/141 #40763 <kanze@lts.sel.alcatel.de>
- Newsgroups: comp.std.c++
- Subject: Re: Explicit constructor call vs Temporaries
- Date: 2 Feb 1996 15:49:12 GMT
- Organization: ?
- Approved: clamage@eng.sun.com (comp.std.c++)
- Message-ID: <9602021214.AA07865@lts.sel.alcatel.de>
- References: <4e6plv$idn@eclipse.eng.sc.rolm.com> <4eq5p2$fpu@fsuj01.rz.uni-jena.de>
- NNTP-Posting-Host: taumet.eng.sun.com
- Content-Type: text
- In-Reply-To: mkt@isun04.inf.uni-jena.de's message of 01 Feb 1996 09:54:08 PST
- Content-Length: 3667
- X-Lines: 125
- Originator: clamage@taumet
-
- In article <4eq5p2$fpu@fsuj01.rz.uni-jena.de>
- mkt@isun04.inf.uni-jena.de (Tilo Koerbs) writes:
-
- |> About the error message in this posted code:
-
- |> > class T {
- |> > T();
- |> > ~T();
- |> > }
- |> >
- |> > class X {
- |> > X();
- |> > ~X();
- |> > f(T& t);
- |> > }
- |> >
- |> > int main() {
- |> > X x;
- |> > x.f(T()); // Compiler complained on this line
- |> > }
-
- |> The 'temporary' (it is an UNNAMED) T()-object is NOT const!
- |> Consider:
- |> class T {
- |> public:
- |> T();
- |> ~T();
- |> void nonConstFct() {}
- |> };
-
- |> int main() {
- |> T().nonConstFct(); // Allowed!!!
- |> }
-
- |> And so the compiler should have no problem with this code!
- |> I compiled it without any problem!
-
- Except that the rules forbid binding a temporary to a non-const
- reference, independantly of whether the temporary is const or not.
- (See section 8.5.3 in the draft standard: "If the initializer
- expression is an lvalue ... Otherwise, the reference shall be to a
- non-volatile const type."
-
- Both g++ 2.7.2 and Sun CC 3.0.1 (the old cfront version) issue
- warnings about this. Curiously enough, Sun CC 4.0.1 doesn't, on this
- platform (Sun CC 4.1), although I seem to remember warnings from this
- compiler under Solaris. The Sun warnings state "anachronism", and in
- fact, this rule was added to the language (at least five or six years
- ago), so some older compilers may not be aware of it.
-
- The rule was introduced to avoid errors in cases like the following:
-
- void
- incr( int& i )
- {
- i ++ ;
- }
-
- void
- user()
- {
- unsigned x( 5 ) ;
- incr( x ) ;
- }
-
- In the call to `incr', the compiler must convert x to an int; the
- result of such a conversion is a temporary. Before the rule was
- adapted, the temporary was bound to the reference, and modified by the
- function `incr'. This is generally *NOT* what the author of user
- wanted or expected (since `x' remains unchanged). Note that this is
- not a problem with const references, since there is presumably no
- modification to get lost.
-
- The solution I'm using (since yesterday, when I thought of it:-) is to
- add a function to T:
-
- T&
- T::lvalue()
- {
- return *this ;
- }
-
- And in the main, above:
-
- int
- main()
- {
- X x ;
- x.f( T().lvalue() ) ;
- return 0 ;
- }
-
- As you point out, the temporary isn't const, so I can call a non-const
- function (like `lvalue') on it. And a reference *is* an lvalue (by
- definition), so it can bind to a non-const reference.
-
- This solution has the advantage (IMHO) of requiring the user to say,
- yes, I know that I'm going to modify a temporary, but that's what I
- want. It also retains const-safety; as the function `lvalue' is not
- const, it cannot be called on a const object.
-
- The major disadvantage is that it requires adding a function to T.
- For classes where one expects this type of behavior (e.g.: auto_ptr),
- one would probably add the function. But the user who needs it
- exceptionally for a class where it is not the normal case is stuck.
- (I have a case where I need it from ostrstream!) Of course, there is
- always derivation:
-
- class MyStrStream : public ostrstream
- {
- public :
- ostrstream& lvalue() { return *this ; }
- } ;
-
- I'm not sure, but I think that `static_cast< T& >( T() )' should also
- work. (This is OK for the occasional exceptional usage, but for cases
- where I expect my user to normally use a temporary, I'll provide the
- derived class.)
-
- --
- James Kanze Tel.: (+33) 88 14 49 00 email: kanze@gabi-soft.fr
- GABI Software, Sarl., 8 rue des Francs-Bourgeois, F-67000 Strasbourg, France
- Conseils, Θtudes et rΘalisations en logiciel orientΘ objet --
- -- A la recherche d'une activitΘ dans une region francophone
-
-
- [ comp.std.c++ is moderated. Submission address: std-c++@ncar.ucar.edu.
- Contact address: std-c++-request@ncar.ucar.edu. The moderation policy is
- summarized in http://reality.sgi.com/employees/austern_mti/std-c++/policy.html
- ]
-